﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Transactions;
using context;
using entities;

namespace DataAccessLibrary.DAL
{
    public class BookingDAO
    {
        public List<CheckIn> SelectCheckingHistory(int cusID)
        {
            using (var ctx = new BlueMDataContext())
            {
                List<CheckIn> list = new List<CheckIn>();
                    
                   var listCheckIn = ctx.Bookings.Where(b => b.CustomerID == cusID).SelectMany(p=> p.CheckIns);

                return listCheckIn.ToList();

            }
        }

        public List<vTotalCheck> SelectTotalCheck(DateTime date, int check)
        {
            using (var ctx = new BlueMDataContext())
            {
                if (check == 0)
                    return ctx.vTotalChecks.Where(p => p.CheckInDate < date && p.CheckInDate > date.AddDays(-7)).ToList();
                else
                    return ctx.vTotalChecks.Where(p => p.CheckOutDate < date && p.CheckOutDate > date.AddDays(-7)).ToList();
            }
        }

        public bool InsertBooking(Booking booking, List<CheckIn> lstCheckIn)
        {
            using (var ctx = new BlueMDataContext())
            {
                using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TimeSpan(0, 0, 30)))
                {
                    List<int> roomId = lstCheckIn.Select(checkIn => checkIn.RoomID).ToList();
                    if (CheckAvailableRoom(roomId, lstCheckIn[0].CheckInDate, lstCheckIn[0].CheckOutDate))
                    {
                        var lst = new EntitySet<CheckIn>();
                        foreach (CheckIn chk in lstCheckIn)
                        {
                            lst.Add(chk);
                        }
                        booking.CheckIns = lst;
                        ctx.Bookings.InsertOnSubmit(booking);
                        ctx.SubmitChanges();
                        scope.Complete();

                        return true;
                    }
                }
            }
            throw new Exception("Room List Not available");
        }


        public bool UpdateBooking(Booking booking)
        {
            using (var ctx = new BlueMDataContext())
            {
                Booking bk = SelectBooking(booking.BookingID);
                bk.CustomerID = booking.CustomerID;
                ctx.SubmitChanges();
            }

            return true;
        }

        private bool CheckAvailableRoom(IEnumerable<int> roomId, DateTime inDate, DateTime outDate)
        {
            if (roomId != null)
            {
                var searchDAO = new SearchDAO();
                List<int> avaiRoomId =
                    searchDAO.SearchRooms(inDate, outDate, 0, 0, 0, false, false, false).Select(p => p.RoomID).ToList();
                return roomId.All(avaiRoomId.Contains);
            }
            return false;
        }

        public Booking SelectBooking(int pBookingID)
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Bookings.First(p => p.BookingID == pBookingID);
            }
        }

        public bool DeleteBooking(int bookingId)
        {
            using (var ctx = new BlueMDataContext())
            {
                Booking booking = SelectBooking(bookingId);
                EntitySet<CheckIn> checkIns = booking.CheckIns;
                if (checkIns.Any(c => c.CheckInEmployee != null))
                {
                    throw new Exception("Can not delete an admited booking");
                }

                foreach (CheckIn c in checkIns)
                {
                    ctx.CheckIns.DeleteOnSubmit(c);
                }
                ctx.Bookings.DeleteOnSubmit(booking);
                ctx.SubmitChanges();
            }

            return true;
        }

        public List<Booking> SelectBookingByCustomerId(int customerId)
        {
            using (var ctx = new BlueMDataContext())
            {
                return ctx.Bookings.Where(
                    p => p.CheckIns.First().CheckInDate > DateTime.Today && p.CustomerID == customerId).ToList();
            }
        }

        public List<Booking> SelectBookingByCustomerId(bool getAvailable, int customerId)
        {
            using (var ctx = new BlueMDataContext())
            {
                DateTime today = DateTime.Now;
                IQueryable<Booking> queryable = ctx.Bookings.Where(p => p.CustomerID == customerId);

                if (getAvailable)
                {
                    queryable = queryable.Where(p => p.CheckIns.First().CheckInDate >= today);
                }
                return queryable.ToList();
            }
        }
    }
}